"""
刷新当前登录用户的好友信息
UserName:当前用户的唯一标识
NickName:名字
RemarkName:备注名
Signature:个人签名
"""
from collections import defaultdict

import itchat

from commons.db import MongoClient
from commons.log import LogFactory
from commons.singleton import singleton
from models.contact_model import ContactModel, RoomMemberModel

logger = LogFactory("contact_service").get_logger()


@singleton
class ContactService:
    logger = LogFactory("contact_service").get_logger()

    def __init__(self):
        self.logger.info("init ContactService")
        self.me = None
        self.contacts = {}
        self.init()

    def init(self):
        friends = self.get_friends()
        me = ContactModel(friends[0])
        self.me = me.jsonfy()

        logger.info("init chatrooms")
        for j in self.get_chatroom():
            # 最后一个user_name和登录者相同
            f = ContactModel(j)
            logger.debug(f)
            self.contacts[f.user_name] = f.jsonfy()

        logger.info("init mps")
        for k in self.get_mps():
            f = ContactModel(k)
            logger.debug(f)
            self.contacts[f.user_name] = f.jsonfy()

        logger.info("init friends")
        for i in friends:
            f = ContactModel(i)
            logger.debug(f)
            self.contacts[f.user_name] = f.jsonfy()

    def refrash(self):
        self.contacts.clear()
        self.init()

    def find_name(self, user_name):
        """寻找联系人"""
        obj = self.contacts.get(user_name)
        name = ''
        if obj:
            if obj['remark_name']:
                name = obj['remark_name']
            elif obj['nick_name']:
                name = obj['nick_name']
        return name

    def get_friends(self):
        # 好友
        friends = itchat.get_friends(True)
        return friends

    def get_chatroom(self):
        # 群聊
        rooms = itchat.get_chatrooms(True)
        return rooms

    def get_mps(self):
        # 公众号
        mps = itchat.get_mps(True)
        return mps


def get_room_members(user_name=None, name=None) -> dict:
    """
    获取现在的群内成员。群成员为空说明这个群已经不存在了

    :param user_name: 群聊的user_name
    :param name: 群聊的名称
    :return:
    """
    if name:
        room = itchat.search_chatrooms(name=name)
        if not room:
            return {}
        user_name = room[0].UserName
    logger.debug("get_room_members:room user_name=%s", user_name)

    # 被删掉的群也可能会出现
    try:
        chatroom = itchat.update_chatroom(user_name, detailedMember=True)  # 获取群内成员
    except:
        return {}
    members = chatroom['MemberList']
    res = {}
    for m in members:
        member = RoomMemberModel(m)
        logger.debug("get_room_member:member %s", member)
        res[member.user_name] = member
    return res


@singleton
class SocialNetworkService:
    """社交网络分析"""

    logger = LogFactory("social_network_service").get_logger()

    def __init__(self):
        self.logger.info("init SocialNetworkService")
        self.friends = {}
        self.chatrooms = defaultdict(dict)
        self.mps = {}

        self.contact_service = ContactService()

    def analyse_group(self):
        logger.debug("analyse group service")
        rooms = itchat.get_chatrooms(update=True)
        for room in rooms:
            obj = ContactModel(room)
            logger.debug("分析群：%s", obj.nick_name)
            cur_members = get_room_members(obj.user_name)
            if not cur_members:
                logger.info("群聊[%s]已经被删除，跳过", obj.nick_name)
                continue
            self.update_room_members(obj.user_name, cur_members)
            # self.chatrooms[obj.user_name] = get_room_members(obj.user_name)

    def update_room_members(self, user_name, cur_members):
        """
        更新某个群聊的成员信息
        #TODO:更新点：成员nick_name、remark_name，

        :param user_name: 群聊的user_name
        :param cur_members: 现在的群内成员
        :return:
        """

        # # 会有和自己同名的群组，目前不知道怎么处理
        # if user_name == self.contact_service.me.user_name:
        #     return
        old_members = self.chatrooms[user_name]  # 初始为空集
        leave_members = old_members.keys() - cur_members.keys()  # set
        new_add_members = cur_members.keys() - old_members.keys()
        room_name = self.contact_service.find_name(user_name)  # 当前的群聊名称
        logger.info("[%s]的人数为%s", room_name, len(cur_members))

        for name in leave_members:
            m = old_members[name]
            if m.active == 1:
                m.leave_chatroom()
                logger.info("%s已离开了群组[%s]", m.nick_name, room_name)

        for name in new_add_members:
            # 只能检测以前未加入过的人，重新加入的不会显示
            m = cur_members[name]
            logger.info("%s加入了群聊[%s]", m.nick_name, room_name)

        cur_members.update(old_members)
        self.chatrooms[user_name] = cur_members


def monitor_contacts():
    """保存联系人信息，用于后续分析"""
    contact_service = ContactService()
    names = MongoClient.get_monitor_room()
    for name in names:  # 群聊名称
        logger.info("保存当前群聊[%s]", name)
        members = get_room_members(name=name)
        for member in members.values():
            member_json = member.jsonfy()
            member_json.update({'chatroom': name})
            MongoClient.save_room_members(member_json)

    # 保存好友信息
    friends = contact_service.get_friends()
    logger.info("保存当前好友信息")
    for friend in friends:
        obj = ContactModel(friend)
        MongoClient.save_friend(obj.jsonfy())
